package com.ruoyi.web.controller;

import com.alibaba.excel.EasyExcel;
import com.ruoyi.web.common.Result;
import com.ruoyi.web.dto.ComplainImportDTO;
import com.ruoyi.web.entity.BlackBaseInfo;
import com.ruoyi.web.entity.BlackComplainDetail;
import com.ruoyi.web.entity.enums.ComplainSourceEnum;
import com.ruoyi.web.entity.enums.GuangdongCityEnum;
import com.ruoyi.web.service.BlackCaseService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 黑产案件查询登记Controller
 */
@RestController
@RequestMapping("/ihcp/blackcase")
public class BlackCaseController {

    // 添加日志对象
    private static final Logger log = LoggerFactory.getLogger(BlackCaseController.class);

    @Resource
    private BlackCaseService blackCaseService;

    /**
     * 获取投诉来源枚举值
     * @return 投诉来源列表
     */
    @GetMapping("/getComplainSources")
    public Map<String, Object> getComplainSources() {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> sources = new ArrayList<>();
        
        for (ComplainSourceEnum source : ComplainSourceEnum.values()) {
            Map<String, String> item = new HashMap<>();
            item.put("code", source.getCode());
            item.put("name", source.getDesc());
            sources.add(item);
        }
        
        result.put("code", 200);
        result.put("msg", "获取成功");
        result.put("data", sources);
        return result;
    }

    /**
     * 获取广东省地市列表（不含深圳）
     * @return 地市列表
     */
    @GetMapping("/getCities")
    public Map<String, Object> getCities() {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> cities = new ArrayList<>();
        
        for (GuangdongCityEnum city : GuangdongCityEnum.values()) {
            Map<String, String> item = new HashMap<>();
            item.put("code", city.getCode());
            item.put("name", city.getName());
            cities.add(item);
        }
        
        result.put("code", 200);
        result.put("msg", "获取成功");
        result.put("data", cities);
        return result;
    }

    /**
     * 查询黑产机构案件信息列表
     * @param params 查询参数，支持以下字段：
     *              - pageNum: 页码
     *              - pageSize: 每页记录数
     *              - complainSource: 投诉来源
     *              - cityCode: 所属地市
     *              - registrant: 登记人
     *              - firstComplainTimeStart: 首次投诉开始时间
     *              - firstComplainTimeEnd: 首次投诉结束时间
     */
    @PostMapping("/listBlackCase")
    public Map<String, Object> listBlackCase(@RequestBody Map<String, Object> params) {
        return blackCaseService.listBlackCase(params);
    }

    /**
     * 添加黑产案件信息
     * @param params 案件信息，包含以下对象：
     *              - blackBaseInfo: 基本信息
     *              - blackOperation: 运作模式
     *              - blackComplainDetails: 投诉详情列表，每个投诉详情包含：
     *                  - complainName: 投诉人姓名
     *                  - complainSource: 投诉来源
     *                  - complainContact: 联系方式
     *                  - amount: 金额
     *                  - damageAmount: 损失金额
     *                  - complainAddress: 投诉地址
     *                  - complainStatus: 投诉状态
     *                  - registrant: 登记人
     *                  - cityCode: 所属地市
     *                  - firstComplainTime: 首次投诉时间
     *                  - complainSolution: 投诉方案
     *              - blackFileInfos: 附件信息列表
     */
    @PostMapping("/addBlackCase")
    public Map<String, Object> addBlackCase(@RequestBody Map<String, Object> params) {
        try {
            return blackCaseService.addBlackCase(params);
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 500);
            result.put("msg", "添加失败：" + e.getMessage());
            return result;
        }
    }

    /**
     * 更新黑产案件信息
     */
    @PostMapping("/updateBlackCase")
    public Map<String, Object> updateBlackCase(@RequestBody Map<String, Object> params) {
        try {
            return blackCaseService.updateBlackCase(params);
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<>();
            result.put("code", 500);
            result.put("msg", "更新失败：" + e.getMessage());
            return result;
        }
    }

    /**
     * 查询黑产机构案件详细信息
     */
    @PostMapping("/getBlackCase")
    public Map<String, Object> getBlackCase(@RequestParam String id) {
        return blackCaseService.getBlackCase(id);
    }

    /**
     * 文件上传
     */
    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map<String, Object> uploadFile(@RequestPart("multipartfiles") MultipartFile[] files, 
                                        @RequestParam String clerkNo) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 文件为空检查
            if (files == null || files.length == 0) {
                result.put("code", 400);
                result.put("msg", "请选择要上传的文件");
                return result;
            }
            
            // 假设只处理第一个文件
            MultipartFile file = files[0];
            String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String fileName = timestamp + file.getOriginalFilename();
            
            // 构造文件信息
            Map<String, Object> fileInfo = new HashMap<>();
            fileInfo.put("uploadUser", clerkNo);
            fileInfo.put("fileName", fileName);
            fileInfo.put("filePath", "http://10.31.131.114/gdcms-web/s3/download/gdcust/ihcp/" + fileName);
            fileInfo.put("uploadTime", new Date());
            
            result.put("msg", "操作成功");
            result.put("code", 200);
            result.put("data", fileInfo);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "上传失败：" + e.getMessage());
        }
        return result;
    }

    /**
     * 导出黑产案件列表
     */
    @PostMapping("/export")
    public void exportToExcel(HttpServletResponse response, @RequestBody(required = false) Map<String, Object> params) {
        try {
            blackCaseService.exportToExcel(response, params);
        } catch (Exception e) {
            log.error("导出失败", e);
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("{\"code\":500,\"msg\":\"导出失败：" + e.getMessage() + "\"}");
            } catch (IOException ex) {
                log.error("写入响应失败", ex);
            }
        }
    }

    /**
     * 导入投诉信息
     */
    @PostMapping("/complain/import")
    public Result<String> importComplainDetails(@RequestParam("file") MultipartFile file,String createBy) {
        try {
            List<String> errorMsgs = blackCaseService.importComplainDetails(file, createBy);
            if (!errorMsgs.isEmpty()) {
                return Result.error("导入过程中存在错误：" + String.join("; ", errorMsgs));
            }
            return Result.success("导入成功");
        } catch (Exception e) {
            log.error("导入失败", e);
            return Result.error("导入失败：" + e.getMessage());
        }
    }


    /**
     * 导出投诉信息模板
     */
    @GetMapping("/complain/template")
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("投诉信息导入模板", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            
            // 使用ClassPathResource读取模板文件
            ClassPathResource templateResource = new ClassPathResource("template/complainDetail_template.xlsx");
            InputStream templateInputStream = templateResource.getInputStream();
            
            // 将模板文件复制到响应输出流
            IOUtils.copy(templateInputStream, response.getOutputStream());
            response.getOutputStream().flush();
        } catch (IOException e) {
            log.error("下载模板失败", e);
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("{\"code\":500,\"msg\":\"下载模板失败：" + e.getMessage() + "\"}");
        }
    }

    /**
     * 导出投诉信息
     */
    @PostMapping("/complain/export")
    public void exportComplainDetails(@RequestBody Map<String, Object> params, 
                                    HttpServletResponse response) throws IOException {
        try {
            log.info("开始导出投诉信息，参数：{}", params);
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("投诉信息", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            // 获取数据
            List<ComplainImportDTO> dataList = blackCaseService.getComplainDetailsForExport(params);
            log.info("查询到 {} 条数据", dataList.size());
            
            // 直接写出数据
            EasyExcel.write(response.getOutputStream(), ComplainImportDTO.class)
                    .sheet("投诉信息")
                    .doWrite(dataList);
                    
        } catch (Exception e) {
            log.error("导出失败", e);
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("{\"code\":500,\"msg\":\"导出失败：" + e.getMessage() + "\"}");
        }
    }

    /**
     * 批量删除投诉信息
     */
    @PostMapping("/complain/batch-delete")
    public Result<String> batchDeleteComplainDetails(@RequestBody List<String> ids) {
        try {
            blackCaseService.batchDeleteComplainDetails(ids);
            return Result.success("批量删除成功");
        } catch (Exception e) {
            log.error("批量删除失败", e);
            return Result.error("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 查询投诉信息列表
     */
    @PostMapping("/complain/list")
    public Result<Map<String, Object>> listComplainDetails(@RequestBody Map<String, Object> params) {
        try {
            // 处理分页参数
            int pageNum = params.get("pageNum") == null ? 1 : Integer.parseInt(params.get("pageNum").toString());
            int pageSize = params.get("pageSize") == null ? 10 : Integer.parseInt(params.get("pageSize").toString());
            params.put("offset", (pageNum - 1) * pageSize);
            params.put("pageSize", pageSize);

            Map<String, Object> result = blackCaseService.listComplainDetails(params);
            return Result.success(result);
        } catch (Exception e) {
            log.error("查询投诉信息失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 更新投诉信息
     */
    @PostMapping("/complain/update")
    public Result<String> updateComplainDetail(@RequestBody BlackComplainDetail complainDetail, String currentUser) {
        try {
            // 设置更新人和更新时间
            complainDetail.setUpdateBy(currentUser);
            complainDetail.setUpdateTime(new Date());
            
            // 如果提供了城市名称，转换为城市编码
            if (StringUtils.isNotBlank(complainDetail.getCityName())) {
                for (GuangdongCityEnum city : GuangdongCityEnum.values()) {
                    if (city.getName().equals(complainDetail.getCityName())) {
                        complainDetail.setCityCode(city.getCode());
                        break;
                    }
                }
            }
            
            blackCaseService.updateComplainDetail(complainDetail);
            return Result.success("更新成功");
        } catch (Exception e) {
            log.error("更新投诉信息失败", e);
            return Result.error("更新失败：" + e.getMessage());
        }
    }

    /**
     * 批量关联投诉信息
     * @param params 包含baseIds和投诉信息
     */
    @PostMapping("/complain/batch-associate")
    public Result<String> batchAssociateComplain(@RequestBody Map<String, Object> params) {
        try {
            // 获取基础ID列表
            @SuppressWarnings("unchecked")
            List<String> baseIds = (List<String>) params.get("baseIds");
            if (baseIds == null || baseIds.isEmpty()) {
                return Result.error("基础ID列表不能为空");
            }

            // 获取投诉信息
            @SuppressWarnings("unchecked")
            Map<String, Object> complainDetail = (Map<String, Object>) params.get("complainDetail");
            if (complainDetail == null) {
                return Result.error("投诉信息不能为空");
            }

            // 获取投诉信息
            @SuppressWarnings("unchecked")
            String createBy = (String) params.get("createBy");
            if (complainDetail == null) {
                return Result.error("投诉信息不能为空");
            }

            blackCaseService.batchAssociateComplain(baseIds, complainDetail,createBy);
            return Result.success("关联成功");
        } catch (Exception e) {
            log.error("批量关联投诉信息失败", e);
            return Result.error("关联失败：" + e.getMessage());
        }
    }

    @PostMapping("/complaint/add")
    @ApiOperation("录入单条投诉记录")
    public Result<String> addComplaint(@RequestBody BlackComplainDetail detail) {
        try {
            // 打印接收到的请求参数
            log.info("接收到的投诉记录参数: {}", detail);
            
            // 生成UUID
            detail.setId(UUID.randomUUID().toString().replace("-", ""));
            
            // 参数校验
            if (StringUtils.isEmpty(detail.getComplainNo())) {
                log.warn("投诉编号为空");
                return Result.error("投诉编号不能为空");
            }
            
            // 设置默认值
            Date now = new Date();
            if (detail.getCreateTime() == null) {
                detail.setCreateTime(now);
            }
            if (detail.getUpdateTime() == null) {
                detail.setUpdateTime(now);
            }
            if (detail.getIsDelete() == null) {
                detail.setIsDelete("0");
            }
            
            // 如果提供了城市名称但没有城市编码，自动转换
            if (StringUtils.isNotBlank(detail.getCityName()) && StringUtils.isEmpty(detail.getCityCode())) {
                log.info("尝试根据城市名称[{}]转换城市编码", detail.getCityName());
                for (GuangdongCityEnum city : GuangdongCityEnum.values()) {
                    if (city.getName().equals(detail.getCityName())) {
                        detail.setCityCode(city.getCode());
                        log.info("城市编码转换成功: {}", city.getCode());
                        break;
                    }
                }
            }
            
            // 调用service层处理
            log.info("开始保存投诉记录，ID: {}", detail.getId());
            blackCaseService.addComplaint(detail);
            
            return Result.success("投诉记录添加成功");
        } catch (Exception e) {
            log.error("添加投诉记录失败，详细错误：", e);
            return Result.error("添加投诉记录失败：" + e.getMessage());
        }
    }

    /**
     * 远程搜索公司名称
     */
    @PostMapping("/remote-search/company")
    public Result<List<BlackBaseInfo>> remoteSearchByCompanyName(@RequestBody Map<String, String> params) {
        try {
            log.info("开始远程搜索公司名称，参数：{}", params);
            List<BlackBaseInfo> results = blackCaseService.remoteSearchByCompanyName(
                params.get("keyword"),
                params.get("companyType"),
                params.get("companyLegalName"),
                params.get("companyCity")
            );
            return Result.success(results);
        } catch (Exception e) {
            log.error("远程搜索公司名称失败", e);
            return Result.error("搜索失败：" + e.getMessage());
        }
    }

    /**
     * 远程搜索法人名称
     */
    @PostMapping("/remote-search/legal")
    public Result<List<BlackBaseInfo>> remoteSearchByLegalName(@RequestBody Map<String, String> params) {
        try {
            log.info("开始远程搜索法人名称，参数：{}", params);
            List<BlackBaseInfo> results = blackCaseService.remoteSearchByLegalName(
                params.get("keyword"),
                params.get("companyName"),
                params.get("companyType"),
                params.get("companyCity")
            );
            return Result.success(results);
        } catch (Exception e) {
            log.error("远程搜索法人名称失败", e);
            return Result.error("搜索失败：" + e.getMessage());
        }
    }

    /**
     * 远程搜索投诉人名称
     */
    @PostMapping("/remote-search/complain")
    public Result<List<BlackComplainDetail>> remoteSearchByComplainName(@RequestBody Map<String, String> params) {
        try {
            log.info("开始远程搜索投诉人名称，参数：{}", params);
            List<BlackComplainDetail> results = blackCaseService.remoteSearchByComplainName(
                params.get("keyword"),
                params.get("cityCode"),
                params.get("complainSource"),
                params.get("complainStatus")
            );
            return Result.success(results);
        } catch (Exception e) {
            log.error("远程搜索投诉人名称失败", e);
            return Result.error("搜索失败：" + e.getMessage());
        }
    }
} 